﻿using TestWebApplication.CommerceTransaction.APIs;
using Microsoft.Commerce.Proxy.TransactionService.v201001;
using System.ServiceModel;
using System;
using System.Security;
using System.Security.Cryptography.X509Certificates;

namespace TestWebApplication.CommerceTransaction
{

    public class CommerceTransactionServiceAdapter : ServiceAdapter
    {
        private const string CommerceContractName = "Microsoft.Commerce.Proxy.TransactionService.v201001";

        public CommerceTransactionServiceAdapter(string serviceUrl, X509Certificate2 cert)
            : base(serviceUrl, cert)
        {
        }

        public PurchaseOutput Purchase(BillingInfo billingInfo, CallerInfo callerInfo, Marketplace marketPlace, PurchaseContext purchaseContext, PurchaseInfoInput purchaseInfo)
        {
            PurchaseInput input = PreparePurchaseInput(billingInfo, callerInfo, marketPlace,purchaseContext, purchaseInfo);

            ChannelFactory<TransactionServiceChannel> clientFactory = new ChannelFactory<TransactionServiceChannel>(this.binding, this.address);

            clientFactory.Endpoint.Contract.Name = CommerceContractName;
            clientFactory.Credentials.ClientCertificate.Certificate = this.clientCert;
            TransactionServiceChannel channel = clientFactory.CreateChannel();
            

            PurchaseOutput output = channel.Purchase(input);


            return output;
        }

        public GetPurchaseOutput GetPurchase(DateRange dateRange, CallerInfo callerInfo, string purchaseId)
        {
            GetPurchaseInput input = PrepareGetPurchaseInput(dateRange, callerInfo, purchaseId);

            ChannelFactory<TransactionServiceChannel> clientFactory = new ChannelFactory<TransactionServiceChannel>(this.binding, this.address);

            clientFactory.Endpoint.Contract.Name = CommerceContractName;
            clientFactory.Credentials.ClientCertificate.Certificate = this.clientCert;
            TransactionServiceChannel channel = clientFactory.CreateChannel();

            GetPurchaseOutput output = channel.GetPurchase(input);


            return output;
        }

        public RefundPurchaseOutput Refund(CallerInfo callerInfo, PaymentMethod paymentMethod, string purchaseId, string refundAmount)
        {
            RefundPurchaseInput input = PrepareRefundInput(callerInfo, paymentMethod, purchaseId, refundAmount);

            ChannelFactory<TransactionServiceChannel> clientFactory = new ChannelFactory<TransactionServiceChannel>(this.binding, this.address);

            clientFactory.Endpoint.Contract.Name = CommerceContractName;
            clientFactory.Credentials.ClientCertificate.Certificate = this.clientCert;
            TransactionServiceChannel channel = clientFactory.CreateChannel();

            RefundPurchaseOutput output = channel.RefundPurchase(input);


            return output;
        }

        public PurchaseInput PreparePurchaseInput(BillingInfo billingInfo, CallerInfo callerInfo, Marketplace marketPlace, PurchaseContext purchaseContext, PurchaseInfoInput purchaseInfo)
        {
            // prepare the create account input;
            PurchaseInput input = new PurchaseInput()
            {
                APIContext = new APIContext()
                {
                    TrackingGuid = Guid.NewGuid()
                },
                BillingInfo = billingInfo,
                CallerInfo = callerInfo,
                Marketplace = marketPlace,
                PurchaseContext = purchaseContext,
                PurchaseInfoInput = purchaseInfo
            };

            return input;
        }

        public GetPurchaseInput PrepareGetPurchaseInput(DateRange dateRange, CallerInfo callerInfo, string purchaseId)
        {
            // prepare the create account input;
            GetPurchaseInput input = new GetPurchaseInput()
            {
                DateRange = dateRange,
                CallerInfo = callerInfo,
                OriginalTrackingGuid = Guid.NewGuid(),
                PurchaseId = purchaseId
            };

            return input;
        }

        public RefundPurchaseInput PrepareRefundInput(CallerInfo callerInfo, PaymentMethod paymentMethod, string purchaseId, string refundAmount)
        {
            // prepare the create account input;
            RefundPurchaseInput input = new RefundPurchaseInput()
            {
                APIContext = new APIContext()
                {
                    TrackingGuid = Guid.NewGuid()
                },
                CallerInfo = callerInfo,
                PaymentMethod = paymentMethod,
                PurchaseId = purchaseId,
                RefundAmount = refundAmount,
                RefundType = "RefundFullPurchase",
                RefundPurchaseContext = new RefundPurchaseContext()
                {
                    TimeStamp = DateTime.Now,
                },
                IsImmediate = false,
                RevertProductFlag = false,
            };

            return input;
        }

        
    }
}
